/**
 * kue shim
 */

const Queue = require('kue');
const lodash = require('lodash');
const Promise = require('bluebird');

// Queue shims
lodash.defaults(Queue.prototype, {
    // Assign add method with promise
    add(type, data, options) {
        options = Object.assign({
            priority: null,
            backoff: null,
            attempts: 0,
            delay: 0,
            ttl: 0
        }, options);

        return Promise.try(() => {
            return this.create(type, data);
        })
        .then(job => {
            if(options.priority !== null) {
                job.priority(options.priority);
            }
            if(options.backoff !== null) {
                job.backoff(options.backoff);
            }

            if(options.attempts) {
                job.attempts(options.attempts);
            }
            if(options.ttl) {
                job.ttl(options.ttl);
            }
            if(options.delay) {
                job.delay(options.delay);
            }

            return new Promise((resolve, reject) => {
                job.save(err => {
                    if(err) {
                        reject(err);
                        return;
                    }

                    resolve(job);
                });
            });
        });
    },
    // Assign remove method with promise
    remove(jobId) {
        return this.get(jobId)
        .then(job => {
            if(!job) {
                return;
            }

            return job.removeAsync();
        });
    },
    get(jobId, options = {}) {
        return new Promise((resolve, reject) => {
            Queue.Job.get(jobId, (err, job) => {
                if(err) {
                    reject(err);

                    return;
                }

                resolve(job || null);
            });
        })
        .catch(err => {
            if(err && options.require) {
                throw err;
            }

            return null;
        });
    }
});

// Job shims
lodash.defaults(Queue.Job.prototype, {
    getAttempts() {
        const maxAttempts = +this._max_attempts || 1;
        const attempts = +this._attempts || 0;

        return {
            remaining: Math.max(0, maxAttempts - attempts),
            max: maxAttempts,
            made: attempts
        };
    },
    removeAsync() {
        return new Promise((resolve, reject) => {
            this.remove(err => {
                if(err) {
                    reject(err);

                    return;
                }

                resolve();
            });
        });
    }
});

module.exports = Queue;
